以前:
next dev底层:
xxxxxxxxxxWebpack现在:
xxxxxxxxxxTurbopack (Stable)默认启用。构建和热更新速度显著提升。
面试一句话:
Next.js 16 makes Turbopack the default stable bundler, replacing Webpack as the primary build system.
这是我认为最值得学的。
Next.js 15 之前
很多缓存是隐式的:
xxxxxxxxxxawait fetch(url)开发者经常搞不清:
xxxxxxxxxx这个会缓存吗?这个会 ISR 吗?什么时候重新验证?Next.js 16
变成:
xxxxxxxxxx"use cache";显式缓存。
例如:
xexport async function getPosts() { "use cache"; return db.post.findMany();}缓存行为由开发者明确声明。(CodeForGeek)
面试官很可能问:
Why was "use cache" introduced?
答案:
To make caching explicit and predictable instead of relying on implicit framework behavior.
以前:
xxxxxxxxxxSSRSSGISR三套体系。
现在:
xxxxxxxxxxCache Components+PPR统一了很多思路。
可以做到:
xxxxxxxxxx页面外壳提前渲染↓动态部分后续流式返回类似:
xxxxxxxxxxHeaderSidebarLoading...然后:
xxxxxxxxxxPostsCommentsProfile逐步流出来。
以前:
xxxxxxxxxxmiddleware.ts现在推荐:
xxxxxxxxxxproxy.tsNext 团队认为:
middleware 这个名字让大家误以为是 Express Middleware。
实际上它更像:
xxxxxxxxxxNetwork Boundary所以改名了。
这个面试里属于加分知识点。
Next.js 16 默认搭配 React 19.2。
意味着你可以直接使用:
useEffectEvent面试可能问:
Which React version is bundled with Next.js 16?
答案:
React 19.2.
以前:
xxxxxxxxxxuseMemouseCallbackmemo写得到处都是。
现在:
xxxxxxxxxxReact Compiler能够自动做很多记忆化优化。
所以未来面试很可能出现:
Do we still need useMemo everywhere?
答案:
Less than before. React Compiler can automatically optimize many cases.
Next.js 16 对导航进行了进一步优化:
xxxxxxxxxxLayout DeduplicationIncremental Prefetching减少重复请求。
页面切换更快。
"use cache")
React 18 官方新增了 5 个 Hooks。这是开发中最常用、面试最爱考的部分:
useDeferredValue(延迟值 Hook)text),返回一个该状态的“延迟版本”(deferredText)。当用户疯狂打字时,deferredText 会保持原值不变,React 会在浏览器有空闲时间的第一时刻去悄悄计算并渲染新列表,并且这个计算过程是可随时打断的。useDeferredValue 的优势:智能降级,绝不卡顿
它不需要你设置任何延迟时间。React 会把这个值标记为“低优先级”。
useDeferredValue 的魔法:当 React 在后台渲染低优先级的延时列表时,如果用户突然又按了一个键,React 会立即中止(Abort)当前的列表渲染,回过头去优先处理用户的键盘输入。等输入处理完了,再重新开始渲染列表。
useDeferredValue完美适用场景(纯前端 CPU 密集型)它的核心舞台是:数据已经在前端(本地内存中),但因为数据量太大,渲染/过滤时会导致页面卡顿。
大数据量本地搜索/过滤:
- 比如前端一次性从后端拿到了 5000 条城市数据或员工列表,用户在输入框输入时,需要实时在本地
filter并渲染大列表。复杂图表/仪表盘实时联动:
- 用户拖动一个滑块(Slider)改变参数,页面上的 ECharts 复杂折线图、热力图需要同步跟着变。渲染图表极其消耗 CPU,用它能保证滑块拖动时丝滑不卡顿。
富文本编辑器/Markdown 实时预览:
- 用户在左侧疯狂敲字输入(高优先级),右侧实时解析成 HTML 并渲染复杂的数学公式或代码高亮(低优先级,用
useDeferredValue延后预览)。长列表的标签页(Tab)切换:
- 从 Tab A 切换到拥有几千个 DOM 节点的 Tab B。可以用它包裹 Tab 的状态,让点击 Tab 按钮时瞬间高亮,而厚重的 Tab B 内容在后台慢慢渲染。
useDeferredValue绝对禁用场景(涉及外部 I/O)只要操作跨越了 React 内存边界,去和外部世界打交道,就必须用防抖(Debounce)或节流(Throttle):
网络请求(远程搜索/联想输入框) ➡️ 必须用防抖
- 每打一个字就要发一次 API 调用的场景。
频繁写入本地存储(LocalStorage / IndexedDB) ➡️ 必须用防抖/节流
- 比如实时自动保存用户的草稿,高频写入硬盘会严重挤占浏览器主线程。
埋点与日志上报 ➡️ 必须用防抖/节流
- 监听用户滚动(Scroll)或鼠标移动(MouseMove)并发送分析日志,必须节流,否则瞬间发送几百条请求。
赠送:一个防抖做不到的“神级用户体验”
使用
useDeferredValue做本地过滤时,官方非常推荐一个配合方案:在后台悄悄计算时,让老列表变淡(半透明),提示用户“正在搜索中”。这在防抖里很难做(因为防抖在等待时,组件根本不知道用户在打字),但在
useDeferredValue里只需要一行判断:xxxxxxxxxximport { useState, useDeferredValue } from 'react';function SearchPage({ allItems }) {const [text, setText] = useState("");const deferredText = useDeferredValue(text);// 💡 核心魔法:如果当前输入的值 和 正在延时计算的值不一致,说明用户正在打字,React 正在后台计算const isStale = text !== deferredText;const filteredItems = allItems.filter(item => item.includes(deferredText));return (<div><input value={text} onChange={e => setText(e.target.value)} />{/* 当正在计算时,给列表加上 opacity-50 的类名,变半透明,体验极佳 */}<div style={{ opacity: isStale ? 0.5 : 1, transition: 'opacity 0.2s' }}><HugeList items={filteredItems} /></div></div>);}
useTransition / startTransition(过渡状态 Hook)你用得上的场景:长列表标签页(Tab)切换、点击按钮渲染大量 DOM 元素。
核心作用:它和 useDeferredValue 是同门师兄弟。区别在于,useDeferredValue 负责包裹一个状态值,而 useTransition 负责包裹一个触发更新的函数。
xxxxxxxxxxconst [isPending, startTransition] = useTransition();// 当点击 Tab 时,将耗时的切换操作标记为“过渡/低优先级状态”startTransition(() => { setActiveTab('heavy-list-tab'); });用户体验红利:通过 isPending 状态,你可以非常轻松地在切换期间让页面呈现半透明或显示一个局部的 Loading 提示。
useId(生成唯一 ID Hook)<label htmlFor={id}>),或者需要将前端生成的 DOM ID 传给第三方库。Math.random() 生成 ID,会导致 SSR 服务端生成的 HTML 里的 ID 和浏览器 Hydration(注水)后的 ID 不匹配,React 会疯狂报错。
useSyncExternalStore(同步外部存储 Hook)window.innerWidth、网络在线状态)时。
useInsertionEffect(插入副作用 Hook)useLayoutEffect。专门用来在 DOM 发生变动之前,向页面动态注入 <style> 标签,避免在并发渲染过程中由于动态注入样式导致浏览器频繁引发重排(Reflow)。
onClick)里的多次 setState 会合并。现在,无论是在 Promise、setTimeout、异步 fetch 还是原生 DOM 事件中,只要在同一个事件循环里,所有的 setState 都会被合并为一次渲染。setState 立即触发渲染,必须使用官方提供的 flushSync 强制同步执行。
createRoot 全新应用挂载 APIReactDOM.render,改用全新的 createRoot。只有这一行代码改了,React 18 的并发机制和自动批处理等引擎才会真正启动。
如果你做的是 Next.js、Remix 项目或者公司内部的 SSR 架构,这是最震撼的升级:
<Suspense> 包裹。等列表在服务器异步算完了,React 会把这部分的 HTML 以“流(Stream)”的形式追加发送给浏览器,并自动把 Loading 替掉。
<Suspense> 包裹的区域,React 会优先“注水”激活用户点击的那块区域,让页面立刻能响应交互,其余不重要的部分等会儿再说。
在日常开发中,有些更新如果你不知道,可能会排查一整天的 Bug:
useEffect 执行两次(StrictMode)<StrictMode>,组件挂载时 useEffect 会按照:挂载 -> 卸载 -> 再次挂载 的顺序执行,导致你的 useEffect 内部的代码会连续执行两次。useEffect 里必须写完备的 清理函数(Cleanup Function)。因为在未来的并发模式下,React 组件可能会频繁被后台卸载并重新挂载(比如离屏缓存特性 Offscreen),如果不写清理函数(比如清除定时器、取消事件监听),会发生严重的内存泄漏。
return 如果不返回具体的 DOM,就必须返回 null,否则会报错。React 18 放宽了限制,组件现在可以合法地直接返回 undefined、数字、字符串等任何可以直接渲染的类型。
可以这样流畅地把它们分类组织:
createRoot 开启了 并发渲染 与 全场景自动批处理 的时代。useDeferredValue 和 useTransition 两个防卡顿大招;针对服务端渲染和高频组件,有了稳定 ID 的 useId。useEffect 的双击执行 规范了整个社区编写副作用时必须写清理函数的习惯。
新特性很多,但是只需要关注下面这些即可。
如果是面试,React 19 不需要把所有 API 都背下来,但有几个特性已经属于高频题了。
React 19 最大的目标之一就是简化表单提交和异步状态管理。
以前:
xxxxxxxxxxconst [loading, setLoading] = useState(false);async function handleSubmit() { setLoading(true); try { await saveData(); } finally { setLoading(false); }}需要自己管理:
React 19:
xxxxxxxxxxconst [error, submitAction, isPending] = useActionState(saveData, null);React 自动管理提交状态。
中文
React 19 引入了 Actions,允许开发者直接把异步操作作为 Action 提交,React 会自动管理 pending、error 和更新流程。
English
React 19 introduced Actions, which simplify async mutations by letting React manage pending, error, and update states automatically.
用于处理表单 Action 的状态。
xxxxxxxxxxconst [state, formAction] = useActionState(action, initialState);以前:
xxxxxxxxxxuseStateuseEffecttry/catch一堆逻辑。
现在:
xxxxxxxxxxuseActionState统一处理。
useActionState combines form submission and state management into a single Hook.
获取当前表单提交状态。
xxxxxxxxxxconst { pending } = useFormStatus();例如:
xxxxxxxxxx<button disabled={pending}> Submit</button>以前:
xxxxxxxxxxloading stateprops drillingcontext现在直接从表单上下文获取。
useFormStatus allows components inside a form to access the current submission status without passing props.
高频面试题。
实现 Optimistic UI。
例如发评论:
以前:
xxxxxxxxxx点击发送↓等待接口↓成功后显示用户感觉慢。
现在:
xxxxxxxxxxconst [comments, addOptimisticComment] = useOptimistic(initialComments);点击发送:
xxxxxxxxxx立即显示评论↓后台请求↓失败回滚
中文
useOptimistic 可以在服务器响应之前先更新 UI,提高用户体验。
English
useOptimistic lets the UI update immediately before the server confirms the change, providing a faster user experience.
这是 React 19 最有技术含量的 API。
以前:
xxxxxxxxxxuseEffect(() => { fetchData();}, []);React 19:
xxxxxxxxxxconst data = use(fetchPromise);React 可以:
xxxxxxxxxxPromise Pending↓自动 SuspensePromise Resolved↓继续渲染
中文
use() 可以直接读取 Promise 或 Context,如果 Promise 未完成,React 会自动挂起当前渲染并交给 Suspense 处理。
English
The use() API allows components to read Promises directly. If the Promise is still pending, React suspends rendering and lets Suspense handle the loading state.
React 终于支持:
xxxxxxxxxx<title /><meta /><link />直接写在组件里。
例如:
xxxxxxxxxxfunction Page() { return ( <> <title>Home</title> <meta name="description" content="Homepage" /> </> );}React 自动处理 Head。
React 可以协调:
xxxxxxxxxxpreload()preinit()preconnect()例如:
xxxxxxxxxxpreload("/hero.jpg", { as: "image",});作用:
xxxxxxxxxx更早加载资源减少瀑布请求提高性能
React 19 之前:
xxxxxxxxxxforwardRef()React 19:
xxxxxxxxxxfunction MyInput({ ref }) { return <input ref={ref} />;}直接支持。
Is forwardRef still required in React 19?
回答:
In many cases, no. React 19 allows ref to be passed as a normal prop.
以前:
xxxxxxxxxxHydration failed很难定位。
现在会告诉你:
xxxxxxxxxxServer:"Hello"Client:"Hello World"定位速度快很多。
你提供的这份 React 19 新特性面试核心总结非常准确、含金量极高,结构和对比也非常清晰!
如果是在面试中,能把这 9 点(尤其是你筛选出的 Top 5)清晰地说明白“以前怎么做”和“现在怎么做”,就已经能够击败 90% 的面试者了。
不过,如果以 2026 年当下的面试标准来看,这份总结还差了 4 个极其高频、甚至属于“底层变革”的考点。面试官非常喜欢通过这些来看你对 React 19 的理解是否流于表面。
我为你把这几个缺失的“大底牌”补全在下面:
Server Components (RSC) 与 Server Actions这是 React 19 在架构上的最大变革,你提到了 Actions,但如果不提 RSC,这个全家桶就不完整。
以前:React 只能在浏览器(客户端)运行。要拿数据必须写 useEffect 发 Ajax 请求。
现在:React 19 正式将服务端组件(RSC)纳入核心架构。组件默认在服务器上渲染,直接连接数据库。
Server Actions:允许你在客户端组件里,像调用普通本地函数一样调用一个在服务器运行的异步函数。
xxxxxxxxxx// actions.js'use server' // 💡 声明这是个服务端 Actionexport async function addToCart(id) { await db.query('...'); // 直接操作数据库,不暴露 API 接口给前端}面试金句:React 19 模糊了前端和后端的边界,通过 Server Actions 实现了端到端的类型安全和无缝数据交互。
React Compiler (曾经的 React Forget)这是前端圈期待了数年的核武器级性能优化特性,虽然它作为独立工具链运行,但它是伴随 React 19 正式落地的。
useMemo、useCallback 和 React.memo。代码变得极其臃肿,而且容易写错依赖项导致闭包陷阱。useMemo 和 useCallback 已经基本沦为历史遗留产物。开发者可以回归纯粹的 JS 写法,把性能优化完全交给编译器。
Context 可以直接当做 Provider 使用这是一个非常人性化的语法糖简化。
以前:
xxxxxxxxxx<ThemeContext.Provider value="dark">...</ThemeContext.Provider>现在:不需要写
xxxxxxxxxx.Provider
了,直接把 Context 当组件用:
xxxxxxxxxx<ThemeContext value="dark">...</ThemeContext>面试金句:消除了繁琐的 .Provider 后缀,代码更加直观和干净。
对 DOM 操作极为友好的一个细节改动。
以前:如果要在元素挂载时用 ref 绑定一个第三方库(如 Swiper),并在卸载时清理,必须写在 useEffect 里。
现在:
xxxxxxxxxxref
属性接收的函数可以直接返回一个清理函数(类似于 useEffect 的 return)。
xxxxxxxxxx<div ref={(node) => { if (node) { const instance = initAwesomeLibrary(node); return () => instance.destroy(); // 💡 卸载时自动执行清理 }}} />
React Compiler(谈宏观视野:标志着 React 告别手动性能优化的旧时代)Server Components & Server Actions(谈架构变革:颠覆了前后端数据交互模型)use()(谈异步革新:直接在渲染树中消费 Promise,配合 Suspense 彻底干掉 useEffect 拿数据)useActionState() & useFormStatus()(谈表单生态:React 官方下场统一了异步表单状态管理的乱象)useOptimistic()(谈用户体验:原生支持乐观更新,以前需要大费周章自己写回滚逻辑)ref as prop(谈 DX 开发体验:终于去掉了反人类的 forwardRef)
一句话总结(面试版)
中文
React 19 主要围绕异步数据处理和表单操作进行了增强,引入了 use()、Actions、useActionState、useOptimistic 等 API,让 Suspense、Server Components 和表单交互变得更加简单。
English
React 19 focuses on improving async data handling and form interactions. New features such as use(), Actions, useActionState, and useOptimistic make Suspense, Server Components, and user interactions much easier to implement.